// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: declaration of .
//   $Id$



// Actions.h: interfaces for all the action related classes.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_ACTIONS_H__68F1F737_007F_4ED2_9D8F_F12FC8A60201__INCLUDED_)
#define AFX_ACTIONS_H__68F1F737_007F_4ED2_9D8F_F12FC8A60201__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "FormControl.h"
#include "IAction.h"
#include <list>
#include <DOM3XPath.h>
typedef std::list<CImplAction*> CImplActionList;

class CImplAction;
class CXFormsElementAction;
//TODO:
//This Implementation of IEventListener only exists as a separate class
//	because of the constructors for CImpl(Action) in the parsing system.
class CImplActionEventListener
	:public CComObjectRootEx<CComSingleThreadModel>
	,public IDispatchImpl<IEventListener,&IID_IEventListener,&LIBID_DOM2EventsLib,2,0>
{
public:
	BEGIN_COM_MAP(CImplActionEventListener)
		COM_INTERFACE_ENTRY(IEventListener)
		COM_INTERFACE_ENTRY(IDispatch)
	END_COM_MAP()

	STDMETHOD(handleEvent)(IDOMEvent * evt);
	DECLARE_PROTECT_FINAL_CONSTRUCT()
	void init(IEventTarget * pTarget);
	IAction * m_pAction;
protected:
	void FinalRelease();
private:
	CComPtr<IEventTarget> m_pTarget;
};
/*
class CImplAction_
{

public:
	CComBSTR m_sEvent;
	virtual HRESULT Invoke();
protected:
	CComBSTR m_sObserver;

private:
	CComObject<CImplActionEventListener> * m_pEventListener;
	CComPtr<IEventTarget> m_pTarget;
}
*/
class CImplAction  
	:public CImpl
	,public IAction
{
	friend class CXFormsParseAction;
	//CImplActionEventListener is actually supposed to be an interface
	//	on this class, but because it is COM and there is a lot of messing
	//	with constructors osv. It is a separate class.
	friend class CImplActionEventListener;
public:

	virtual void notifyDelete();
	//TODO: get rid of this constructor
	CImplAction(CXFormsXFormsElement * pXForms);
	CImplAction(CXFormsElementAction * pXFormsElement);
	CImplAction();
	virtual ~CImplAction();
	virtual HRESULT init(CImpl * pParent);//,bool bInitChain = true);

	HRESULT Invoke();
	virtual CXFormsXFormsElement * getXFormsElement();
	virtual HRESULT getEvent(BSTR * sEvent);
	virtual HRESULT AddChild(CImpl * pChild);
	CImpl * m_pControl;
	CComBSTR m_sEvent;
protected:
	virtual HRESULT GetXPathContext(IXMLDOMNode ** ppNode);
	CComBSTR m_sObserver;
	bool m_bHasResolvedOwnModel;
public:
	virtual CIdResolver * GetIdResolver(void) const;
private:
	CComObject<CImplActionEventListener> * m_pEventListener;
	CComPtr<IEventTarget> m_pTarget;
	virtual HRESULT  PerformAction();
	HRESULT PerformNextChildAction(CMap<CImpl *,CImpl *, CImpl *,CImpl *>::CPair * pPair);
	CImplActionList m_ActionList;

	HRESULT PrepareIterationNodeset(unsigned long * lIterations);
	CComPtr<IXPathResult> m_pContextSet;
	HRESULT FlushIterationNodeset();
	CComBSTR m_sIterate;
	CComBSTR m_sWhile;
	CComBSTR m_sIf;
	unsigned long m_ulCurrentIteration;
	HRESULT InvokeIteratively();
	HRESULT InvokeConditionally();
	bool TestWhileCondition();
	bool TestIfCondition();

};


#endif // !defined(AFX_ACTIONS_H__68F1F737_007F_4ED2_9D8F_F12FC8A60201__INCLUDED_)
